using System.Collections.Generic;
using System.Linq;
using SkaldRogueLike.Main.CellContent.Items;
using SkaldRogueLike.Main.Constants.Enumerations;

namespace SkaldRogueLike.Main.CellContent.Creatures
{
    public class Wardrobe
    {
        private Dictionary<EquipOn, Equipment> Equipped { get; set; }
        private Dictionary<EquipOn, Equipment[]> EquippedOnHand { get; set; }

        public Wardrobe()
        {
            Equipped = new Dictionary<EquipOn, Equipment>
                           {
                               {EquipOn.Head, null},
                               {EquipOn.Neck, null},
                               {EquipOn.Body, null},
                               {EquipOn.Hands, null},
                               {EquipOn.Weist, null},
                               {EquipOn.Legs, null},
                               {EquipOn.Feet, null},
                               {EquipOn.BothHands, null}
                           };
            EquippedOnHand = new Dictionary<EquipOn, Equipment[]>
                               {
                                   {EquipOn.Hand, new Equipment[2]},
                                   {EquipOn.Finger, new Equipment[2]}
                               };
        }

        public List<Equipment> Equip(Equipment equipment)
        {
            var putOff = new List<Equipment>(2);
            switch (equipment.PlaceType)
            {
                case EquipOn.Hand:
                case EquipOn.Finger:
                    if (EquippedOnHand[equipment.PlaceType][0] == null)
                        EquippedOnHand[equipment.PlaceType][0] = equipment;
                    else
                    {
                        putOff.Add(EquippedOnHand[equipment.PlaceType][1]);
                        EquippedOnHand[equipment.PlaceType][1] = equipment;
                    }
                    break;
                case EquipOn.BothHands:
                    if (Equipped[equipment.PlaceType] != null)
                    {
                        putOff.Add(Equipped[equipment.PlaceType]);
                        Equipped[equipment.PlaceType] = null;
                    }
                    else if (EquippedOnHand[EquipOn.Hand].All(it => it != null))
                    {
                        putOff.AddRange(EquippedOnHand[EquipOn.Hand]);
                        EquippedOnHand[EquipOn.Hand][0] = null;
                        EquippedOnHand[EquipOn.Hand][1] = null;
                    }
                    break;
                default:
                    putOff.Add(Equipped[equipment.PlaceType]);
                    Equipped[equipment.PlaceType] = equipment;
                    break;
            }
            return putOff;
        }

        public void Unequip(Equipment equipment)
        {
            switch (equipment.PlaceType)
            {
                case EquipOn.Hand:
                case EquipOn.Finger:
                    if (EquippedOnHand[equipment.PlaceType][0] == equipment)
                        EquippedOnHand[equipment.PlaceType][0] = null;
                    else
                        EquippedOnHand[equipment.PlaceType][1] = equipment;
                    break;
                case EquipOn.BothHands:
                    EquippedOnHand[EquipOn.Hand][0] = null;
                    EquippedOnHand[EquipOn.Hand][1] = null;
                    break;
                default:
                    Equipped[equipment.PlaceType] = null;
                    break;
            }
        }

        public List<Equipment> ShowEquipped()
        {
            return Equipped.Values.Where(it => it != null)
                .Concat(EquippedOnHand.Values.SelectMany(it => it).Where(it => it != null))
                    .OrderBy(it => it.PlaceType).ToList();
        }

        public int GetEquipmentBonus(Bonus type)
        {
            var result = 0;
            result += Equipped.Values
                        .Where(it => it != null && it.BonusType == type).Sum(it => it.Mod);
            result += EquippedOnHand.Values.SelectMany(it => it)
                        .Where(it => it != null && it.BonusType == type).Sum(it => it.Mod);
            return result;
        }
    }
}